﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace DotNet.Helper
{
    /// <summary>
    /// WCF帮助类
    /// </summary>
    public class WcfHelper
    {
        private static NetTcpBinding _tcpBinding;
        /// <summary>
        /// 默认TcpBinding
        /// </summary>
        public static NetTcpBinding DefaultBinding
        {
            get
            {
                if (_tcpBinding == null)
                {
                    try
                    {
                        _tcpBinding = new NetTcpBinding("defaultBinding");
                        return _tcpBinding;
                    }
                    catch (Exception ex)
                    {
                        Log4netHelper.Log.WriteError("未找到默认配置节点", ex);
                    }

                    _tcpBinding = new NetTcpBinding(SecurityMode.None)
                    {
                        Name = "_defaultBinding",
                        CloseTimeout = new TimeSpan(0, 1, 0),
                        OpenTimeout = new TimeSpan(0, 1, 0),
                        ReceiveTimeout = new TimeSpan(0, 30, 0),
                        SendTimeout = new TimeSpan(0, 10, 0),
                        TransactionFlow = false,
                        TransferMode = TransferMode.Streamed,
                        TransactionProtocol = TransactionProtocol.OleTransactions,
                        HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
                        ListenBacklog = 10,
                        MaxBufferPoolSize = int.MaxValue,
                        MaxBufferSize = int.MaxValue,
                        MaxConnections = 2000,
                        MaxReceivedMessageSize = long.MaxValue,
                    };
                    _tcpBinding.ReaderQuotas = new XmlDictionaryReaderQuotas
                    {
                        MaxArrayLength = 16384,
                        MaxDepth = 32,
                        MaxStringContentLength = 8192,
                        MaxBytesPerRead = 4096,
                        MaxNameTableCharCount = 16384,
                    };
                    _tcpBinding.ReliableSession.Ordered = true;
                    _tcpBinding.ReliableSession.InactivityTimeout = new TimeSpan(0, 10, 0);
                    _tcpBinding.ReliableSession.Enabled = false;
                }
                return _tcpBinding;
            }
        }

        /// <summary>
        /// 服务通道检查间隔 10秒
        /// </summary>
        public const double ChkInterval = 10 * 1000;

        /// <summary>
        /// 获取服务地址
        /// </summary>
        /// <param name="serverType"></param>
        /// <param name="serverIP"></param>
        /// <param name="serverPort"></param>
        /// <returns></returns>
        public static Uri GetSvrUri(Type serverType, string serverIP, int serverPort)
        {
            string serverName = serverType.Name;
            var urlService = new Uri($"net.tcp://{serverIP}:{serverPort}/{serverName}");

            return urlService;
        }

        /// <summary>
        /// 反射获取服务的ip和端口
        /// </summary>
        /// <param name="serverType">服务类型</param>
        /// <param name="ip">ip</param>
        /// <param name="port">端口</param>
        /// <returns></returns>
        public static bool GetIPAndPort(Type serverType, out string ip, out int port)
        {
            ip = string.Empty;
            port = 0;
            try
            {
                string key = $"{serverType.Assembly.GetName().Name}.WCF";
                var configVal = AppSettingsHelper.GetStringByKey(key, "");
                if (string.IsNullOrWhiteSpace(configVal))
                {
                    Log4netHelper.Log.WriteError("无可用服务地址配置");
                    return false;
                }
                var tar = configVal.Split(':');
                if (tar.Length < 1)
                {
                    Log4netHelper.Log.WriteError("IP端口格式非法");
                    return false;
                }
                ip = tar[0];
                if (!int.TryParse(tar[1], out port))
                {
                    Log4netHelper.Log.WriteError("IP端口格式非法");
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                Log4netHelper.Log.WriteError("", ex);
                return false;
            }
        }
    }
}
